﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FinalPointSet.Model.Asset;
using FinalPointSet.Model.Constant;
using FinalPointSet.Model.Constant.Message;
using FinalPointSet.Model.Constants;
using FinalPointSet.Model.Manager;
using FinalPointSet.Model.Model;
using FinalPointSet.Model.Model.FieldMapping;
using FinalPointSet.Model.Model.Knowledge;
using FinalPointSet.Model.Util;
using ICSharpCode.AvalonEdit.Highlighting;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using static FinalPointSet.Model.Manager.MessageManager;
using Clipboard = System.Windows.Clipboard;
namespace FinalPointSet.ViewModel.Page.MainView
{
    public partial class FieldMappingViewModel : ObservableObject, IDisposable
    {
        [ObservableProperty]
        private List<Language> _languages = [];
        /// <summary>
        /// 表名
        /// </summary>
        [ObservableProperty]
        private string _TableName = "table";
        /// <summary>
        /// 库名
        /// </summary>
        [ObservableProperty]
        private string _Database = "database";
        /// <summary>
        /// 备注
        /// </summary>
        [ObservableProperty]
        private string _Comment = string.Empty;
        /// <summary>
        /// 输入SQL
        /// </summary>
        [ObservableProperty]
        private string _InputSQL = "";
        /// <summary>
        /// 输出SQL
        /// </summary>
        [ObservableProperty]
        private string _TargetSQL = string.Empty;
        /// <summary>
        /// 数据源映射
        /// </summary>
        [ObservableProperty]
        private List<DataSourceMapping> _DataSourceMappings = new();

        /// <summary>
        /// 当前选中的数据源映射
        /// </summary>
        [ObservableProperty]
        private DataSourceMapping _SelectedDataSourceMapping = new();
        /// <summary>
        /// 目标数据源
        /// </summary>
        [ObservableProperty]
        private ObservableCollection<DataSource> _TargetDataSources = new();
        /// <summary>
        /// 当前选中的目标数据源
        /// </summary>
        [ObservableProperty]
        private DataSource _SelectedTargetDataSource = new();
        /// <summary>
        /// 高亮样式
        /// </summary>
        [ObservableProperty]
        private IHighlightingDefinition? _highlightingDefinition;
        /// <summary>
        /// 保存按钮可见性
        /// </summary>
        [ObservableProperty]
        private Visibility _CopyButtonVisibility = Visibility.Hidden;

        public FieldMappingViewModel()
        {
            InitResource();
            //监听数据源集合资源变化
            AssetManager.Instance.OnJsonObjectListUpdate += OnResourceUpdate;
        }

        /// <summary>
        /// 重新初始化资源
        /// </summary>
        /// <param name="type"></param>
        private void OnResourceUpdate(Type type)
        {
            if (type == typeof(DataSource) || type == typeof(DataSourceMapping) || type == typeof(FormatTemplate))
                InitResource();
        }

        /// <summary>
        /// 初始化资源
        /// </summary>
        private void InitResource()
        {
            //加载语言、映射关系
            DataSourceMappings = DataSourceMappingHelper.GetDataSourceMappings();
            //设置当前目标语言类型
            SelectedDataSourceMapping = DataSourceMappings[0];
            TargetDataSources = new(SelectedDataSourceMapping.MappingRules.Select(mr => mr.TargetDataSource));
            //设置高亮
            //设置代码高亮
            ObjectPair<IHighlightingDefinition>? hightLightDef = AssetManager.Instance.GetObjectListElementByKey<IHighlightingDefinition>(Path.HighLightDefinition, "SQL");
            if (hightLightDef != null)
            {
                HighlightingDefinition = hightLightDef.Value;
            }
        }

        [RelayCommand]
        private void Transform()
        {
            //校验输入SQL&来源&目标类型
            if (string.IsNullOrEmpty(InputSQL))
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Warning, "来源字段不能为空!"));
                return;
            }
            else if (SelectedDataSourceMapping == null)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Warning, "来源类型不能为空!"));
                return;
            }
            else if (SelectedTargetDataSource == null)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Warning, "目标类型不能为空!"));
                return;
            }

            //提取映射规则
            DataSource sourceDataSource = SelectedDataSourceMapping.SourceDataSource;
            DataSource targetDataSource = SelectedTargetDataSource;
            DataSourceMappingRule? dsMappingRule = DataSourceMappingHelper.FindDataSourceMappingRule(sourceDataSource, targetDataSource);
            if (dsMappingRule == null)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, "无法找到匹配的映射规则!"));
                return;
            }

            //提取映射生成的模板
            FormatTemplate? formatTemplate = DataSourceMappingHelper.FindFormatTemplate(targetDataSource);
            if (formatTemplate == null)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, "无法找到匹配的生成模板!"));
                return;
            }

            //格式化
            try
            {
                Table table = SQLParser.StringToTable(InputSQL, TableName, Database, Comment);
                TargetSQL = SQLFormatter.GetSQL(table, formatTemplate, dsMappingRule);
            }
            catch (Exception e)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, $"字段映射失败! 错误原因:{e.Data}"));
                return;
            }

            try
            {
                if (string.IsNullOrEmpty(TargetSQL))
                    return;

                Copy();
                CopyButtonVisibility = Visibility.Visible;
            }
            catch (Exception e)
            {
                Debug.Print($"FieldMappingViewModel.Transform(),复制文本到剪贴板失败!,失败原因:{e.Message}");
            }
        }

        /// <summary>
        /// 设置
        /// </summary>
        [RelayCommand]
        private static void Setting()
        {
            Debug.Print("FieldMappingViewModel.Setting()");
            PageUtil.Instance.Navigate(PageUtil.FieldMappingSettingPage);
        }

        /// <summary>
        /// 重置输入
        /// </summary>
        [RelayCommand]
        private void Reset()
        {
            Debug.Print("FieldMappingViewModel.Reset()");
            InputSQL = String.Empty;
            TargetSQL = String.Empty;
            CopyButtonVisibility = Visibility.Hidden;
        }

        /// <summary>
        /// 复制结果
        /// </summary>
        [RelayCommand]
        private void Copy()
        {
            if (!string.IsNullOrEmpty(TargetSQL))
            {
                Clipboard.SetText(TargetSQL);
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, "映射成功, 结果已复制剪贴板"));
            }
        }

        /// <summary>
        /// 来源语言下拉框选中变更
        /// </summary>
        [RelayCommand]
        private void SelectionChanged()
        {
            if (SelectedDataSourceMapping == null) return;
            Debug.Print($"FieldMappingViewModel.SelectionChanged(),当前选中:{SelectedDataSourceMapping.SourceDataSource.Name}");
            //更新数据
            TargetDataSources = new(SelectedDataSourceMapping.MappingRules.Select(mr => mr.TargetDataSource));
        }

        public void Dispose()
        {
            AssetManager.Instance.OnJsonObjectListUpdate -= OnResourceUpdate;
        }
    }
}
